123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- using UnityEngine;
- using UnityEditor;
- namespace ExternPropertyAttributes.Editor
- {
- [CustomPropertyDrawer(typeof(ExpandableAttribute))]
- public class ExpandablePropertyDrawer : PropertyDrawerBase
- {
- protected override float GetPropertyHeight_Internal(SerializedProperty property, GUIContent label)
- {
- System.Type propertyType = PropertyUtility.GetPropertyType(property);
- if (typeof(ScriptableObject).IsAssignableFrom(propertyType))
- {
- ScriptableObject scriptableObject = property.objectReferenceValue as ScriptableObject;
- if (scriptableObject == null)
- {
- return GetPropertyHeight(property);
- }
- if (property.isExpanded)
- {
- using (SerializedObject serializedObject = new SerializedObject(scriptableObject))
- {
- float totalHeight = EditorGUIUtility.singleLineHeight;
- using (var iterator = serializedObject.GetIterator())
- {
- if (iterator.NextVisible(true))
- {
- do
- {
- SerializedProperty childProperty = serializedObject.FindProperty(iterator.name);
- if (childProperty.name.Equals("m_Script", System.StringComparison.Ordinal))
- {
- continue;
- }
- bool visible = PropertyUtility.IsVisible(childProperty);
- if (!visible)
- {
- continue;
- }
- float height = GetPropertyHeight(childProperty);
- totalHeight += height;
- }
- while (iterator.NextVisible(false));
- }
- }
- totalHeight += EditorGUIUtility.standardVerticalSpacing;
- return totalHeight;
- }
- }
- else
- {
- return GetPropertyHeight(property);
- }
- }
- else
- {
- return GetPropertyHeight(property) + GetHelpBoxHeight();
- }
- }
- protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
- {
- EditorGUI.BeginProperty(rect, label, property);
- System.Type propertyType = PropertyUtility.GetPropertyType(property);
- if (typeof(ScriptableObject).IsAssignableFrom(propertyType))
- {
- ScriptableObject scriptableObject = property.objectReferenceValue as ScriptableObject;
- if (scriptableObject == null)
- {
- EditorGUI.PropertyField(rect, property, label, false);
- }
- else
- {
- // Draw a foldout
- Rect foldoutRect = new Rect()
- {
- x = rect.x,
- y = rect.y,
- width = EditorGUIUtility.labelWidth,
- height = EditorGUIUtility.singleLineHeight
- };
- property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, label, toggleOnLabelClick: true);
- // Draw the scriptable object field
- float indentLength = ExternalCustomEditorGUI.GetIndentLength(rect);
- float labelWidth = EditorGUIUtility.labelWidth - indentLength + ExternalCustomEditorGUI.HorizontalSpacing;
- Rect propertyRect = new Rect()
- {
- x = rect.x + labelWidth,
- y = rect.y,
- width = rect.width - labelWidth,
- height = EditorGUIUtility.singleLineHeight
- };
- EditorGUI.BeginChangeCheck();
- property.objectReferenceValue = EditorGUI.ObjectField(propertyRect, GUIContent.none, property.objectReferenceValue, propertyType, false);
- if (EditorGUI.EndChangeCheck())
- {
- property.serializedObject.ApplyModifiedProperties();
- }
- // Draw the child properties
- if (property.isExpanded)
- {
- DrawChildProperties(rect, property);
- }
- }
- }
- else
- {
- string message = $"{typeof(ExpandableAttribute).Name} can only be used on scriptable objects";
- DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
- }
- EditorGUI.EndProperty();
- }
- private void DrawChildProperties(Rect rect, SerializedProperty property)
- {
- ScriptableObject scriptableObject = property.objectReferenceValue as ScriptableObject;
- if (scriptableObject == null)
- {
- return;
- }
- Rect boxRect = new Rect()
- {
- x = 0.0f,
- y = rect.y + EditorGUIUtility.singleLineHeight,
- width = rect.width * 2.0f,
- height = rect.height - EditorGUIUtility.singleLineHeight
- };
- GUI.Box(boxRect, GUIContent.none);
- using (new EditorGUI.IndentLevelScope())
- {
- EditorGUI.BeginChangeCheck();
- SerializedObject serializedObject = new SerializedObject(scriptableObject);
- using (var iterator = serializedObject.GetIterator())
- {
- float yOffset = EditorGUIUtility.singleLineHeight;
- if (iterator.NextVisible(true))
- {
- do
- {
- SerializedProperty childProperty = serializedObject.FindProperty(iterator.name);
- if (childProperty.name.Equals("m_Script", System.StringComparison.Ordinal))
- {
- continue;
- }
- bool visible = PropertyUtility.IsVisible(childProperty);
- if (!visible)
- {
- continue;
- }
- float childHeight = GetPropertyHeight(childProperty);
- Rect childRect = new Rect()
- {
- x = rect.x,
- y = rect.y + yOffset,
- width = rect.width,
- height = childHeight
- };
- ExternalCustomEditorGUI.PropertyField(childRect, childProperty, true);
- yOffset += childHeight;
- }
- while (iterator.NextVisible(false));
- }
- }
- if (EditorGUI.EndChangeCheck())
- {
- serializedObject.ApplyModifiedProperties();
- }
- }
- }
- }
- }
|